package blog

import kotlinx.coroutines.*

/**
 * 基本使用
 */

//协程是轻量级的线程
//fun main(args: Array<String>) {
//
//    // GlobalScope 中启动了一个新的协程，这意味着新协程的生命周期只受整个应用程序的生命周期限制
//    GlobalScope.launch {
//        //挂起，非阻塞主线程
//        delay(1000)
//        println("world!")
//    }
//
//    println("hello,")
//    //保证jvm 存活
////    Thread.sleep(2000)
//
//    //另一种阻塞方式
//    runBlocking {
//        delay(2000)
//    }
//}

//runBlocking可以包装整个main函数，将整个main函数转换成协程，这样可以直接阻塞住主线程
//fun main()= runBlocking {
//    GlobalScope.launch {
//        delay(1000)
//        println("world!")
//    }
//    println("hello ")
//    delay(2000)
//}

//使用join()函数等待挂起函数执行完再结束jvm
//fun main() = runBlocking {
//    val job = GlobalScope.launch {
//        delay(2000)
//        println("world!")
//    }
//
//    println("hello**")
//    job.join()
//}

//在执行操作所在的指定作用域内启动协程
//可以在这个作用域中启动协程而无需显式 join
//fun main() = runBlocking { // this: CoroutineScope
//    launch { // 在 runBlocking 作用域中启动一个新协程
//        delay(1000L)
//        println("World!")
//    }
//    println("Hello,")
//}


//runBlocking 与 coroutineScope 可能看起来很类似，因为它们都会等待其协程体以及所有子协程结束。
// 主要区别在于，runBlocking 方法会阻塞当前线程来等待，
// 而 coroutineScope 只是挂起，会释放底层线程用于其他用途。
// 由于存在这点差异，runBlocking 是常规函数，而 coroutineScope 是挂起函数
//fun main() = runBlocking { // this: CoroutineScope
//    launch {
//        delay(200L)
//        println("Task from runBlocking")  //  2
//    }
//
//    coroutineScope { // 创建一个协程作用域
//        launch {
//            delay(500L)
//            println("Task from nested launch")  // 3
//        }
//
//        delay(200L)
//        println("Task from coroutine scope") // 这一行会在内嵌 launch 之前输出  1
//    }
//
//    println("Coroutine scope is over") // 这一行在内嵌 launch 执行完毕后才输出    4
//}

//fun main() = runBlocking {
//    //启动了 10 万个协程
//    repeat(100_000){
//        launch {
//            delay(500L)
//            println(".")
//        }
//    }
//}

//在 GlobalScope 中启动的活动协程并不会使进程保活。它们就像守护线程
fun main() = runBlocking {
    GlobalScope.launch {
        repeat(1000) { i ->
            delay(500L)
            println("I'm sleeping $i ...")
        }
    }
    delay(5000L) // 在延迟后退出
//    println("start...")
}